package com.leiden.uni;

import android.content.Context;
import android.util.Log;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.dcloud.feature.uniapp.annotation.UniJSMethod;
import io.dcloud.feature.uniapp.bridge.UniJSCallback;
import io.dcloud.feature.uniapp.common.UniModule;
import leiden.interfaces.LeidenConnectResultCallBack;
import leiden.interfaces.LeidenPrintfResultCallBack;
import leiden.interfaces.LeidenScanDeviceCallBack;
import leiden.manager.LeidenManager;
import leiden.manager.connect.LeidenDeviceManager;
import leiden.model.LeidenDevice;
import leiden.model.LeidenEnvPrinterModel;
import leiden.model.LeidenPrinterModel;
import leiden.utils.PermissionUtil;

public class LeidenUniModule extends UniModule {

    static String TAG = "LeidenUniModule";

    static String SCAN_BLE_EVENT = "scanBle";
    static String CONNECT_EVENT = "connect_event";

    // 操作成功
    static int resultCode = 1;

    static int resultNoLocalPermissions = 2;

    LeidenConnectResultCallBack leidenConnectResultCallBack = new LeidenConnectResultCallBack() {
        @Override
        public void success(LeidenDevice leidenDevice) {
            Map<String,Object> params=new HashMap<>();
            params.put("name",leidenDevice.getName());
            params.put("mac",leidenDevice.getMac());
            params.put("result","success");
            mUniSDKInstance.fireGlobalEventCallback(CONNECT_EVENT, params);
        }

        @Override
        public void close(LeidenDevice leidenDevice) {
            Map<String,Object> params=new HashMap<>();
            params.put("name",leidenDevice.getName());
            params.put("mac",leidenDevice.getMac());
            params.put("result","close");
            mUniSDKInstance.fireGlobalEventCallback(CONNECT_EVENT, params);
        }

        @Override
        public void fail(LeidenDevice leidenDevice) {
            Map<String,Object> params=new HashMap<>();
            params.put("name",leidenDevice.getName());
            params.put("mac",leidenDevice.getMac());
            params.put("result","fail");
            mUniSDKInstance.fireGlobalEventCallback(CONNECT_EVENT, params);
        }
    };

    LeidenScanDeviceCallBack leidenDevice = new LeidenScanDeviceCallBack() {
        @Override
        public void scanDevice(LeidenDevice leidenDevice) {
            Map<String,Object> params=new HashMap<>();
            params.put("name",leidenDevice.getName());
            params.put("mac",leidenDevice.getMac());
            Log.e(TAG,"扫描到设备：" + leidenDevice.toString());
            mUniSDKInstance.fireGlobalEventCallback(SCAN_BLE_EVENT, params);
        }

        @Override
        public void beginScan() {
        }

        @Override
        public void stopScan() {
        }
    };

    @UniJSMethod
    public void init() {
        PermissionUtil.checkPrintfPermission(mUniSDKInstance.getContext());
    }

    @UniJSMethod
    public void close() {
        getLeidenDeviceManager().close();
    }

    @UniJSMethod
    public void listerDevice() {
        getLeidenDeviceManager().addConnectResultCallBack(leidenConnectResultCallBack);
    }

    @Override
    public void onActivityDestroy() {
        super.onActivityDestroy();
        getLeidenDeviceManager().removeScanDeviceCallBack(leidenDevice);
        getLeidenDeviceManager().removeConnectResultCallBack(leidenConnectResultCallBack);
        getLeidenDeviceManager().stopSearch();
    }


    // 扫描蓝牙
    @UniJSMethod
    public int scan() {

        // 位置权限判断
        if (!PermissionUtil.checkLocationPermission(mUniSDKInstance.getContext())) {
            return resultNoLocalPermissions;
        }

        LeidenDeviceManager leidenDeviceManager = getLeidenDeviceManager();
        leidenDeviceManager.addScanDeviceCallBack(leidenDevice);
        leidenDeviceManager.beginSearch();
        return resultCode;
    }

    // 返回值代表是否已经发起，此接口为异步接口，监听事件的返回
    @UniJSMethod
    public void connect(String mac,UniJSCallback uniJSCallback) {
        LeidenDeviceManager leidenDeviceManager = getLeidenDeviceManager();
        boolean connect = leidenDeviceManager.connect(mac);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("result",connect);

        if (uniJSCallback != null) {
            uniJSCallback.invoke(jsonObject);
        }

    }

    // 数据发送 1 代表 发送成功，-2代表发送失败，-1代表未连接
    @UniJSMethod
    public void writer(String content,UniJSCallback uniJSCallback) {
        byte[] bytes = content.getBytes(StandardCharsets.UTF_8);
        LeidenDeviceManager leidenDeviceManager = getLeidenDeviceManager();
        int result = leidenDeviceManager.write(bytes);
        if (uniJSCallback != null) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("result",result);
            uniJSCallback.invoke(jsonObject);
        }
    }


    @UniJSMethod
    public void isConnect(UniJSCallback uniJSCallback) {
        boolean connect = getLeidenDeviceManager().isConnect();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("result",connect);
        if (uniJSCallback != null) {
            uniJSCallback.invoke(jsonObject);
        }
    }

    // 打印
    @UniJSMethod
    public void printfLabels(final JSONObject jsonObject, final UniJSCallback uniJSCallback) {

        try {
            List<LeidenPrinterModel> leidenPrinterModels = new ArrayList<>();

            JSONArray labels = jsonObject.getJSONArray("labels");
            for (int i = 0; i < labels.size(); i++) {
                JSONObject labelJSONObject = labels.getJSONObject(i);
                leidenPrinterModels.add(LeidenUtils.createLeidenPrinterModel(labelJSONObject));
            }

            LeidenManager leidenManager = getLeidenManager();
            leidenManager.printfAPLLabels(leidenPrinterModels, new LeidenPrintfResultCallBack() {
                @Override
                public void callBack(int result) {

                    /**
                     //打印成功
                     int LEIDEN_PRINTF_RESULT_SUCCESS = 1;
                     //打印错误
                     int LEIDEN_PRINTF_RESULT_CMD_ERROR = 2;
                     //蓝牙未连接
                     int LEIDEN_PRINTF_RESULT_BLUETOOTH = 3;
                     */
                    JSONObject resultJSON = new JSONObject();
                    resultJSON.put("resultType", result);
                    if (result == LeidenPrintfResultCallBack.LEIDEN_PRINTF_RESULT_SUCCESS) {
                        resultJSON.put("result", "打印成功");
                    } else if (result == LeidenPrintfResultCallBack.LEIDEN_PRINTF_RESULT_CMD_ERROR) {
                        resultJSON.put("result", "打印错误");
                    } else if (result == LeidenPrintfResultCallBack.LEIDEN_PRINTF_RESULT_BLUETOOTH) {
                        resultJSON.put("result", "蓝牙未连接");
                    }
                    if (uniJSCallback != null) {
                        uniJSCallback.invoke(result);
                    }
                }

                @Override
                public void progress(int total, int progress) {

                }
            });
        } catch (Exception e) {
            e.printStackTrace();
            if (uniJSCallback != null) {
                JSONObject resultJSON = new JSONObject();
                resultJSON.put("resultType", LeidenPrintfResultCallBack.LEIDEN_PRINTF_RESULT_CMD_ERROR);
                resultJSON.put("result", "打印错误，请检查传入数据是否正常 " + e.getMessage());
                uniJSCallback.invoke(resultJSON);
            }
        }



    }

    // 设置环境变量
    @UniJSMethod
    public void setCurrentEnviron(JSONObject jsonObject) {
        LeidenManager leidenManager = getLeidenManager();
        leidenManager.setCurrentEnviron(LeidenUtils.createLeidenEnvPrinterModel(jsonObject));
    }

    // 得到当前环境变量
    @UniJSMethod
    public void getCurrentEnviron(UniJSCallback uniJSCallback) {
        LeidenManager leidenManager = getLeidenManager();
        LeidenEnvPrinterModel leidenEnvPrinterModel = leidenManager.getLeidenEnvPrinterModel();
        JSONObject jsonObject = LeidenUtils.toJSONObject(leidenEnvPrinterModel);
        if (uniJSCallback != null) {
            uniJSCallback.invoke(jsonObject);
        }
    }


    private LeidenManager getLeidenManager() {
        Context context = this.mUniSDKInstance.getContext();
        return LeidenManager.getInstance(context);
    }


    private LeidenDeviceManager getLeidenDeviceManager() {
        Context context = this.mUniSDKInstance.getContext();
        return LeidenDeviceManager.getInstance(context);
    }

    @UniJSMethod
    public void log(String content) {
        Log.e(TAG,content);
    }
}
